Skip to content

[torchlib] Promote mixed dtypes in aten::pow.Tensor_Tensor - #3207

Open
Mohammad Sohail Shaikh (sohailshk) wants to merge 1 commit into
microsoft:mainfrom
sohailshk:fix/pow-tensor-type-promotion
Open

Mohammad Sohail Shaikh (sohailshk) wants to merge 1 commit into
microsoft:mainfrom
sohailshk:fix/pow-tensor-type-promotion

Conversation

@sohailshk

Copy link
Copy Markdown

ONNX Pow returns the dtype of its base, but torch promotes the result when the two tensors differ. aten_pow had a TODO: Add type promotion, so:

  • torch.pow(int64 tensor, float32 tensor) was exported with an int64 output (values truncated, e.g. [[1,2,3]] ** [[0.5],[2.0]] gave integers) while torch returns float32.
  • torch.pow(float32 tensor, float64 tensor) was exported as float32; torch returns float64.
  • torch.pow(float32 tensor, bool tensor) was exported with a bool exponent, which Pow does not accept (invalid graph).

The fix casts the operands to the dtype torch.result_type would pick: the float operand wins over an integer or bool one; between two floats the dimensioned operand wins over a zero-dim one, otherwise the wider one (float16 with bfloat16 gives float32). A float base with an integer exponent is left untouched, since Pow accepts that directly. Integer-only mixes (e.g. int32 ** int64, where torch returns int64) are unchanged. Python number operands (e.g. _operator::pow(SymInt, 2)) skip the new path.

The exporter's FX type-promotion pass has skipped pow since pytorch/pytorch#139527, and #2213 suggested adding the casts in torchlib's pow.

Test: test_pow_tensor_tensor_mixed_dtypes in e2e_ops_tests.py (7 cases, exported with the dynamo exporter and compared with eager through ONNX Runtime). On main 5 cases fail (Type (tensor(...)) of output arg (pow_1) ... does not match expected type, or an invalid bool input); the two guard cases (float base, int exponent) pass on both. With the change all 7 pass, as do the other pow e2e tests.

Not tested: GPU; int8/uint8 exponents or bases (ONNX Runtime has no Pow kernel for them, a separate problem).

ONNX Pow returns the dtype of the base, so pow(int64 tensor, float tensor) was exported with an int64 result (values truncated) and pow(float32 tensor, float64 tensor) as float32, while torch promotes to the float dtype. Cast the operands to the dtype torch.result_type picks, treating zero-dim tensors as torch does.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

1 participant